package net.uhuijia.user.usertoken.service.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import net.uhuijia.appbase.service.CrudService;
import net.uhuijia.config.SysSettingConfigHelper;
import net.uhuijia.constants.DBConst;
import net.uhuijia.sys.syssetting.clientservice.SysSettingClientService;
import net.uhuijia.user.usermall.persistence.model.UserMall;
import net.uhuijia.user.usertoken.persistence.dao.UserTokenDao;
import net.uhuijia.user.usertoken.persistence.model.UserToken;
import net.uhuijia.user.usertoken.persistence.model.UserTokenExample;
import net.uhuijia.user.usertoken.persistence.model.UserTokenExample.Criteria;
import net.uhuijia.user.usertoken.persistence.vo.AuthTokenDeviceVo;
import net.uhuijia.user.usertoken.service.UserTokenService;
import net.uhuijia.utils.CalendarHelper;
import net.uhuijia.utils.IdGen;
import net.uhuijia.utils.RandomOrderNumHelper;
import net.uhuijia.utils.StringHelper;


@Service
@Transactional
public class UserTokenServiceImpl
     extends CrudService<UserTokenDao,UserToken,UserTokenExample>
     implements UserTokenService{

    @Autowired
    private SysSettingClientService sysSettingClientService;
    
	@Override
	public UserMall auth(String device, String token) {
		AuthTokenDeviceVo param = new AuthTokenDeviceVo();
		param.setIsEffective(DBConst.TRUE);
		param.setExpireTime(new Date());
		param.setDevice(device);
		param.setToken(token);
		param.setIsOffsite(DBConst.FALSE);
		return mapper.authTokenAndDevice(param);
	}

	@Override
	public UserToken createToken(UserMall user,String device) {
		UserToken userToken = null;
		//查找用户当前有没有可以用的token
		if( null != user && StringHelper.isNotBlanks(device) ){
			UserTokenExample example = new UserTokenExample();
			example.setOrderByClause("EXPIRED_TIME DESC");
			Criteria criteria = example.createCriteria();
			criteria.andIsEffectiveEqualTo(DBConst.TRUE);
			criteria.andDeviceEqualTo(device);
			criteria.andUserIdEqualTo(user.getId());
			criteria.andIsOffsiteEqualTo(DBConst.FALSE);
			List<UserToken> tokens = this.list(example);
			if( tokens.isEmpty() ){
				//生成新的token
				userToken = genToken(user,device);
			}else{//生成新的TOKEN信息
				userToken = tokens.get(0);
				//判断是否单点登入，如果单点登入，则将当前token设置成异地登入，生成新的token
				String isSingleLogin = SysSettingConfigHelper.isSingleLogin.getValue();
				String valueByKey = sysSettingClientService.getValueByKey(SysSettingConfigHelper.isSingleLogin.getKey());
				if( StringHelper.isNotBlanks(valueByKey) ){
					isSingleLogin = valueByKey;
				}
				if( DBConst.TRUE.equals(isSingleLogin) ){
					//判断是否单点登入，如果单点登入，则将当前token设置成异地登入，生成新的token
					userToken.setIsOffsite(DBConst.TRUE);
					mapper.updateByExampleSelective(userToken, example);
					//生成新的token
					userToken = genToken(user,device);
				}else{
					//如果是多点登入，那么刷新当前用户的token失效时间
					userToken = flushToken(userToken);
				}
			}
		}
		return userToken;
	}
	
	/**
	 * 根据用户生成token
	 * @param user
	 * @param device
	 * @return
	 * @author 许小宝
	 */
	public UserToken genToken( UserMall user, String device ){
		UserToken userToken = new UserToken();
		this.initDefalutFields(userToken);
		userToken.setAccessToken(RandomOrderNumHelper.getOrderNumber()+IdGen.uuid());
		userToken.setDevice(device);
		userToken.setExpiredTime(getTokenExpiredTime(null));//默认是7天
		userToken.setIsOffsite(DBConst.FALSE);
		//userToken.setLoginData(loginData);
		userToken.setNickName(user.getNickName());
		userToken.setUserId(user.getId());
		userToken.setTotalCount(1);
		userToken.setUserPhone(user.getPhone());
		this.add(userToken);
		return userToken;
	}
	
	/**
	 * 刷新当前的token有效时间
	 * @param token
	 * @return
	 * @author 许小宝
	 */
	public UserToken flushToken( UserToken token ){
		token.setExpiredTime(getTokenExpiredTime(null));
		this.edit(token);
		return token;
	}
	
	/**
	 * 获得多少天后的时间
	 * @param date
	 * @return
	 */
	public Date getTokenExpiredTime(Date date){
		if( null == date ){
			date = new Date();
		}
	    String tokenExpiredDay = SysSettingConfigHelper.tokenExpiredDay.getValue();
	    String valueByKey = sysSettingClientService.getValueByKey(SysSettingConfigHelper.tokenExpiredDay.getKey());
	    if( StringHelper.isNotBlanks(valueByKey) ){
	    	tokenExpiredDay = valueByKey;
	    }
	    Date dateAfter = CalendarHelper.getDateAfter(date, Integer.parseInt(tokenExpiredDay));
	    return dateAfter;
	}

}